Skip to content

feat(ui,serve): cross-project All Jobs and All Tokens views - #675

Merged
padak merged 5 commits into
mainfrom
claude/global-jobs-view-fc8811
Aug 23, 2026
Merged

feat(ui,serve): cross-project All Jobs and All Tokens views#675
padak merged 5 commits into
mainfrom
claude/global-jobs-view-fc8811

Conversation

@padak

@padak padak commented Aug 23, 2026

Copy link
Copy Markdown
Member

What

Adds cross-project ("all projects") views to the web UI, switchable right where it makes sense — a button on the per-project page:

  • All Jobs (#/jobs-all): one chronological feed across every registered project. Project column, client-side credit estimates per row + a header total over the currently shown rows, relative timestamps (raw ISO in the tooltip), extended status filter (processing/waiting/success/error/warning/terminated/cancelled), partial-failure banner, cross-project detail drawer (SSE logs, re-run/terminate) and shareable deep links (?sel=<alias>/<jobId>). Entered via an All projects button on Jobs; Current project only goes back. Polls at 15 s (vs 8 s per-project) since each tick fans out N Queue API calls server-side.
  • All Tokens (#/tokens-all): read-only token audit across projects with the opt-in last-used derivation (dormant-first, now sorted globally). Row click jumps into that project's Tokens page where mint/rotate/revoke live. Secrets are never present.

Both pages are command-palette-reachable (no extra sidebar rows; the per-project sibling stays highlighted).

Server changes

  • GET /jobs multi-project merge now sorts globally by the requested sort_by/sort_order (default startTime desc), missing values last in both directions, deterministic (project_alias, id) tiebreak — instead of the old alias-then-id grouping that destroyed the per-project chronological order. This also applies to multi-project CLI job list; logged in gotchas.md as (since vNEXT).
  • New GET /token/list: parallel fan-out over registered projects (project repeatable, omitted = all), rows stamped with project_alias, per-project failures degrade into errors[] without aborting the rest, with_last_used supported with the per-token cost documented.
  • Jobs page now renders the previously fetched-but-ignored errors[] envelope.

Implementation notes

  • Shared pieces extracted out of the 600-line page files into jobsShared.tsx / tokensShared.tsx (status colors, drawer, actions, scope/status cells); extraction is behavior-preserving for the per-project pages.
  • Credit rates live in web/frontend/src/config/credits.ts and are an estimate (duration × per-component rate × container size), labeled as such in the UI.
  • No version bump, no changelog entry (release-PR process per docs: version bumps move out of feature PRs into dedicated release PRs #648); version-gated docs tagged vNEXT.

Testing

  • Backend: pytest tests/ full suite green (6047 passed); new coverage for global sort semantics (7 tests) and list_tokens_all aggregation/partial failure/ordering (router forwarding included).
  • Frontend: tsc --noEmit clean, vitest 97 tests green (32 new: credit rate matching, formatCredits boundaries, relative time, token expiry/last-used helpers).
  • Verified live against a 4-project org (kbagent serve --ui): chronological cross-project merge, credits total reacting to the status filter, cross-project drawer + deep-link restore, last-used dormant-first sort, partial-failure banners.

Open in Devin Review

padak added 4 commits August 24, 2026 00:21
Cross-project views are palette-reachable (no sidebar rows); their
per-project sibling stays highlighted while open.
- GET /jobs multi-project merge now sorts globally by the requested
  sort_by/sort_order (default startTime desc, missing values last,
  deterministic (project_alias, id) tiebreak) instead of grouping by
  project alias; applies to CLI multi-project job list too (gotcha
  logged as vNEXT).
- New GET /token/list endpoint: parallel fan-out over registered
  projects (project param repeatable, omitted = all), tokens stamped
  with project_alias, per-project failures degrade into errors[];
  with_last_used applies the dormant-first sort globally.
- New All Jobs page (#/jobs-all): single aggregated feed with Project
  column, client-side credit estimates (config/credits.ts) summed in
  the header, relative timestamps, extended status filter, partial-
  failure banner, cross-project detail drawer + deep links; entered
  via an All projects button on Jobs (reciprocal button goes back).
  Jobs page now also renders the previously ignored errors[].
- New All Tokens page (#/tokens-all): read-only audit across projects
  with opt-in last-used derivation; row click jumps to the project's
  Tokens page where mutations live.
- Shared pieces extracted to jobsShared.tsx / tokensShared.tsx;
  cross-project pages are palette-only (sidebar keeps the per-project
  sibling highlighted).

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

Open in Devin Review

Comment thread src/keboola_agent_cli/services/token_service.py Outdated
…rror list

list_tokens_all merged two different failure kinds into one errors list,
so the All Tokens banner counted a healthy project with one degraded
token as 'could not be listed'. Per-token lookup failures now come back
under a separate token_errors key and render as their own strip.
@padak
padak merged commit 9fc082f into main Aug 23, 2026
2 of 5 checks passed
@padak
padak deleted the claude/global-jobs-view-fc8811 branch August 23, 2026 22:46
padak added a commit that referenced this pull request Aug 23, 2026
* fix(ci): stop the live vNEXT gate turning main and every PR red

`TestLiveRepositoryVnext::test_no_unresolved_placeholder_survives_a_release`
asserted that the live tree carries no `(since vNEXT)` placeholder. That
is not an invariant of this repo -- it is the opposite of the documented
process.

Since #648, a feature PR that documents version-gated behaviour writes
the literal `vNEXT` placeholder and only the release PR rewrites it.
CLAUDE.md says so directly ("Writing `vNEXT` in a feature PR is correct
and stays green"), and TestReleaseModeSelection, added by the same PR as
this assertion, explains that arming the gate outside a release PR
"would demand a contributor delete a placeholder the process requires
them to write".

So main legitimately carries placeholders for most of a release cycle.
The assertion was green only because #670 landed days after 0.90.0 had
just rewritten every one of them. #675 added the first placeholder of
the next cycle and the assertion went red -- on main, and on every open
PR, since a PR run tests the merge commit.

The release-time requirement itself is real and stays enforced where it
can see the base branch's version: the "Unresolved vNEXT placeholder
check" step in ci.yml (`--release-if-newer-than`) and its local twin
`make vnext-check`. A unit test cannot see that version, so it cannot
make this call.

What a test CAN assert is that the live scan works, and that replaces
it: every gate the scanner reports must point at a real line that really
contains the placeholder. Zero hits and ten hits are both valid answers
depending on where in the cycle the tree sits. The neighbouring
"guards the guard" test already covers the globs resolving at all.

* fix(test): anchor the live vNEXT scan on REPO_ROOT, not the cwd

`VnextResidue.path` is repo-root-relative -- find_vnext_residue stores
`path.relative_to(REPO_ROOT).as_posix()` -- so reading it back as a bare
`Path(gate.path)` resolves against the current working directory. The
loop body only executes when the tree actually carries a placeholder,
which is precisely the state main is in now, so running pytest from
anywhere but the repo root raised FileNotFoundError.

Reproduced from tests/ before the change and confirmed green after, from
both the repo root and a subdirectory.

`REPO_ROOT / gate.path` also covers the one fallback branch, where a path
outside the repo is stored absolute: joining an absolute right-hand side
discards the left, yielding that path unchanged.

Raised by Devin review on #678.
@padak padak mentioned this pull request Aug 23, 2026
13 tasks
padak added a commit that referenced this pull request Aug 23, 2026
Batches the nine PRs merged since v0.90.0 (#670, #671, #672, #673, #674, #675, #676, #677, #678) into one version bump and one changelog entry.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant